package com.fastloan.core.apiauth.base.util;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.crypto.Cipher;
import java.security.*;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.HashMap;
import java.util.Map;

/**
 * Rsa加解密工具
 *
 * @author yanwe
 * createTime 2017-12-2017/12/29 9:42
 */
public class RsaUtil {

    private static final Logger logger = LoggerFactory.getLogger(RsaUtil.class);

    /**
     * RSA私钥加密
     *
     * @param data data
     * @param rsaPriKey RSA私钥
     * @return 加密数据
     */
    public static String encryptByRsaPri(String data, String rsaPriKey) {
        try {
            // 获取public key
            byte[] keyBytes = Base64.decodeBase64(rsaPriKey);
            PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey publicKey = keyFactory.generatePrivate(keySpec);
            //java默认"RSA"="RSA/ECB/PKCS1Padding"
            Cipher rsaCipher= Cipher.getInstance("RSA");
            rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encrypted = rsaCipher.doFinal(data.getBytes("UTF-8"));
            return Base64.encodeBase64String(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("RSA私钥加密失败:"+e.getMessage());
            return null;
        }
    }

    /**
     * RSA公钥加密
     *
     * @param data data
     * @param rsaPubKey RSA公钥
     * @return 加密数据
     */
    public static String encryptByRsaPub(String data, String rsaPubKey) {
        try {
            // 获取public key
            byte[] keyBytes = Base64.decodeBase64(rsaPubKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey publicKey = keyFactory.generatePublic(keySpec);
            //java默认"RSA"="RSA/ECB/PKCS1Padding"
            Cipher rsaCipher= Cipher.getInstance("RSA");
            rsaCipher.init(Cipher.ENCRYPT_MODE, publicKey);
            byte[] encrypted = rsaCipher.doFinal(data.getBytes("UTF-8"));
            return Base64.encodeBase64String(encrypted);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("RSA公钥加密失败:"+e.getMessage());
            return null;
        }
    }

    /**
     * RSA私钥解密
     *
     * @param data data
     * @param rsaPriKey RSA私钥
     * @return 解密后的数据
     */
    public static String decryptByRsaPri(String data, String rsaPriKey) {
        try {
            // 获取public key
            byte[] keyBytes = Base64.decodeBase64(rsaPriKey);
            PKCS8EncodedKeySpec privKeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey privateKey = keyFactory.generatePrivate(privKeySpec);
            //java默认"RSA"="RSA/ECB/PKCS1Padding"
            Cipher rsaCipher= Cipher.getInstance("RSA");
            rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] encrypted = rsaCipher.doFinal(Base64.decodeBase64(data));
            return new String(encrypted,"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("RSA私钥解密失败:"+e.getMessage());
            return null;
        }
    }

    /**
     * RSA公钥解密
     *
     * @param data data
     * @param rsaPubKey RSA私钥
     * @return 解密后的数据
     */
    public static String decryptByRsaPub(String data, String rsaPubKey) {
        try {
            // 获取public key
            byte[] keyBytes = Base64.decodeBase64(rsaPubKey);
            X509EncodedKeySpec keySpec = new X509EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PublicKey privateKey = keyFactory.generatePublic(keySpec);
            //java默认"RSA"="RSA/ECB/PKCS1Padding"
            Cipher rsaCipher= Cipher.getInstance("RSA");
            rsaCipher.init(Cipher.DECRYPT_MODE, privateKey);
            byte[] encrypted = rsaCipher.doFinal(Base64.decodeBase64(data));
            return new String(encrypted,"UTF-8");
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("RSA公钥解密失败:"+e.getMessage());
            return null;
        }
    }

    /**
     * 随机生成密钥对
     *
     * @return Key 公钥 value 私钥
     */
    public static Map<String, String> genKeyPair() {
        try {
            // KeyPairGenerator类用于生成公钥和私钥对，基于RSA算法生成对象
            KeyPairGenerator keyPairGen = KeyPairGenerator.getInstance("RSA");//java默认"RSA"="RSA/ECB/PKCS1Padding"
            // 初始化密钥对生成器，密钥大小为96-1024位
            keyPairGen.initialize(1024,new SecureRandom());
            // 生成一个密钥对，保存在keyPair中
            KeyPair keyPair = keyPairGen.generateKeyPair();
            // 得到私钥
            RSAPrivateKey privateKey = (RSAPrivateKey) keyPair.getPrivate();
            // 得到公钥
            RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
            // 得到公钥字符串
            String publicKeyString = Base64.encodeBase64String(publicKey.getEncoded());
            // 得到私钥字符串
            String privateKeyString = Base64.encodeBase64String(privateKey.getEncoded());
            Map<String,String> map = new HashMap<>(1);
            map.put(publicKeyString,privateKeyString);
            return map;
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            logger.error("随机生成密钥对失败:"+e.getMessage());
        }
        return null;
    }
}
